//=========================================================================
// Copyright (C) 2021 The C++ Component Model(COMO) Open Source Project
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//=========================================================================

#ifndef __COTS_CONFIG_H__
#define __COTS_CONFIG_H__

#include "comolock.h"

#ifndef ALIGN4
#define ALIGN4(v) (((v) + 3) & ~3)
#endif

#ifndef ALIGN8
#define ALIGN8(v) (((v) + 7) & ~7)
#endif

/*******
 * Dual-ported RAM (DPRAM) is a type of random-access memory that allows
 *multiple reads or writes to occur at the same time, or nearly the same time,
 *unlike single-ported RAM which allows only one access at a time.
 **/

/*
CPU communication is implemented using DPRAM on the CPU floor, using addresses
0xd0081~0xdffff. According to the application. This piece of address control can
be divided into memory for reading and writing.


//todo : MainPartition + ManagerPartition 是否页对齐比较好

map of partition

    +--------+  <-- MainPartition
    |........|  256 bytes
    +========+  <-- ManagerPartition
    |,,..,,,.|  256*sizeof(Spinlock) bytes, Partition_1 can write, both can read
    |,.,,..,.|  256*sizeof(Spinlock) bytes, Partition_2 can write, both can read
    +========+  <-- Partition_1
    |        |
    |        |  32K bytes
    |        |
    +========+  <-- Partition_2
    |        |
    |        |  32K bytes
    |        |
    +--------+

 ## The producer is responsible for freeing memory.
*/

constexpr int SpinLock_Size = ALIGN4(sizeof(como::Spinlock));

constexpr int MainPartitionStart = ALIGN4(0xd0081);
constexpr int MainPartitionSize =
    ALIGN4(256);  // one element size sizeof(Spinlock)

constexpr int PMALLOC_KEYS = 256;
constexpr int PMALLOC_2_KEYS = PMALLOC_KEYS * 2;

constexpr int ManagerPartitionStart =
                                 ALIGN4(MainPartitionStart + MainPartitionSize);
constexpr int ManagerPartitionSize = PMALLOC_2_KEYS * SpinLock_Size;

constexpr int Partition_1_Start =
                           ALIGN4(ManagerPartitionStart + ManagerPartitionSize);
constexpr int Partition_1_Size = ALIGN4(32000);

constexpr int Partition_2_Start = ALIGN4(Partition_1_Start + Partition_1_Size);
constexpr int Partition_2_Size = ALIGN4(32000);

constexpr int PartitionStart[2] = {Partition_1_Start, Partition_2_Start};
constexpr int PartitionSizes[2] = {Partition_1_Size, Partition_2_Size};
constexpr int PartitionNumber = sizeof(PartitionSizes) / sizeof(int);

#endif  // __COTS_CONFIG_H__
